
package ClientGraphics;

import GameEngine.GameConstants.Graphic;
import GameEngine.GameConstants.Levels;
import GameEngine.Vector;
import Objects.BasicObject;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 * This class will be used to test graphics functionality, through an abstraction, no actual game
 * or server.
 * @author mhfowler
 */
public class GraphicsTest_2 {

    /* millisecond between gamestate updates */
    final int MBGU = 100;

    JFrame mainFrame;
    GraphicsMain gMain;

    public GraphicsTest_2() {
        Dimension levelDimension = new Dimension(1000,600);
        gMain = new GraphicsMain(Levels.ABSTRACT, levelDimension, 1000,1000);
        mainFrame = new JFrame("test");
        mainFrame.setVisible(true);
        mainFrame.setSize(new Dimension(levelDimension.width,levelDimension.height));
        mainFrame.setResizable(true);
        mainFrame.add(gMain.getGraphicsPanel());
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel check = gMain.getGraphicsPanel();
        Graphics g = check.getGraphics();
        Graphics2D g2 = (Graphics2D) g;
        System.out.println("check");
        gMain.initialize();
        System.out.println("done construction");
    }


    public static void main(String[] args) {
       GraphicsTest_2 thisTest = new GraphicsTest_2();
       thisTest.test(2);

}



    /* The second test showcases two characters moving about 500 pixels, over the course of 200 gamestate
     * updates.
     */
    public void test(int a) {

        switch (a) {
            case 1:
        /* basic test of displaying two guys on simple background, transparent pixels,
         * overlap, flicker */
        List<BasicObject> test1 = createTestLevel(1);
        gMain.update(test1);
                break;
            case 2:
                /* this is a case for testing many update states with a timer */
                List<List<BasicObject>> gStates = new LinkedList<List<BasicObject>>();
                /* lets fill this list of game states */
                int counter = 1;
                List<BasicObject> temp;
                Vector move1 = new Vector(1,8);
                Vector move2 = new Vector(1,8);
                Vector move3 = new Vector(6,3);
                temp = createTestLevel(1);
                System.out.println("size " + temp.size());
                while (counter <200) {
                    temp = createTestLevel(1);
                    // move everybody
                    temp.get(0).move(move1.scaleNew(counter));
                    temp.get(1).move(move2.scaleNew(counter));
                    temp.get(2).move(move3.scaleNew(counter));
                    // add gamestate to list
                    gStates.add(temp);
                    counter++;
                    
                }
                /* now create timer which calls update every time interval, and pops off the next
                 * game state in the list */
                 Timer time = new Timer(MBGU,null);
                 TestListener tester = new TestListener(gMain, gStates, time);
                 time.addActionListener(tester);
                 time.start();
                break;
            default:
                break;
        }
    }



    private class TestListener implements ActionListener {

        GraphicsMain gTest;
        Iterator<List<BasicObject>> gameStates;
        Timer parent;

        public TestListener(GraphicsMain g,List<List<BasicObject>> l, Timer p) {
            gTest = g;
            gameStates = l.iterator();
            parent = p;
        }



        public void actionPerformed(ActionEvent e) {
            if (gameStates.hasNext()) {
                gTest.update(gameStates.next());

            }
            else {
                System.out.println("finito");
                parent.stop();
            }
        }
    }







    // creates a list of basic object for testing, using a switch case for different tests
    public static List<BasicObject> createTestLevel(int a) {
        int counter = 0;
        List<BasicObject> toReturn = new LinkedList();
        switch (a) {
            case 1:
                short id = 1;
                BasicObject obj1 = createBasic(1, id, new Vector(50,50), new Vector(35,35));
                toReturn.add(obj1);
                id++;
                BasicObject obj2 = createBasic(2, id, new Vector(60,60), new Vector(35,35));
                id++;
                toReturn.add(obj2);
                BasicObject obj3 = createBasic(1, id, new Vector(70,70), new Vector(35,35));
                id++;
                toReturn.add(obj3);
                break;
            default:
                break;
        }
        return toReturn;
    }


    // creates a basic object, for the purpose of testing
    // uses switch case with integer
    // also takes in id
    public static BasicObject createBasic(int a,short id, Vector minPos, Vector maxPos) {
        BasicObject toReturn = null;
        switch (a) {
            case 1:
                toReturn = new BasicObject(new Vector(1,1), minPos, maxPos, Graphic.PINKPLAYER_WALKLEFT);
                 toReturn.setId(id);
                break;
            case 2:
                toReturn = new BasicObject(new Vector(1,1), minPos, maxPos, Graphic.WIND);
                toReturn.setId(id);
                break;
            default:
                toReturn = new BasicObject(new Vector(1,1), minPos, maxPos, Graphic.PINKPLAYER_WALK);
                 toReturn.setId(id);
                break;
        }
        return toReturn;
    }




}
